﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShredTheLog.Api.DataContracts;
using ShredTheLog.Api.DataContracts.TextChat;
using System.Diagnostics.Contracts;

namespace ShredTheLog.Api
{
    [ContractClass(typeof(TextChat_Contract))]
    public interface ITextChat : IDisposable
    {
        ISessionCredentials Credentials { get; }
        bool IsConnected { get; set; }
        void Update(params ITextChatCommand[] commands);
        bool OpenRoom(string roomName);
        void CloseRoom(string roomName);
        void SendMessage(string roomName, string messageText);
        IObservable<IShortUserInfo> WhenUserEnters { get; }
        IObservable<IUserInfo> WhenUserLeaves { get; }
        IObservable<IEnterRoomUpdate> WhenRoomOpened { get; }
        IObservable<IRoomUserUpdate> WhenUserEntersRoom { get; }
        IObservable<IRoomUserUpdate> WhenUserLeavesRoom { get; }
        IObservable<IAddMessageUpdate> WhenMessageReceived { get; }
        IObservable<IRoomUserUpdate> WhenUserTypes { get; }
        IObservable<SysMessage> WhenSysMessageReceived { get; }
        IObservable<SysMessage> WhenPrivateRequestAnswerReceived { get; }
        IObservable<IUserInfo> WhenPrivateRequestReceived { get; }
        IObservable<Exception> WhenErrorOccurred { get; }
    }

    [ContractClassFor(typeof(ITextChat))]
    internal abstract class TextChat_Contract : ITextChat
    {
        ISessionCredentials ITextChat.Credentials
        {
            get { throw new NotImplementedException(); }
        }

        bool ITextChat.IsConnected
        {
            get { throw new NotImplementedException(); }
            set { throw new NotImplementedException(); }
        }

        void ITextChat.Update(params ITextChatCommand[] commands)
        {
            Contract.Requires(commands != null);
            throw new NotImplementedException();
        }

        bool ITextChat.OpenRoom(string roomName)
        {
            Contract.Requires(!String.IsNullOrWhiteSpace(roomName));
            throw new NotImplementedException();
        }

        void ITextChat.CloseRoom(string roomName)
        {
            Contract.Requires(!String.IsNullOrWhiteSpace(roomName));
            throw new NotImplementedException();
        }

        void ITextChat.SendMessage(string roomName, string messageText)
        {
            Contract.Requires(!String.IsNullOrWhiteSpace(roomName));
            Contract.Requires(!String.IsNullOrEmpty(messageText));
            throw new NotImplementedException();
        }

        IObservable<IShortUserInfo> ITextChat.WhenUserEnters
        {
            get 
            {
                Contract.Ensures(Contract.Result<IObservable<IShortUserInfo>>() != null);
                throw new NotImplementedException(); 
            }
        }

        IObservable<IUserInfo> ITextChat.WhenUserLeaves
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IUserInfo>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IEnterRoomUpdate> ITextChat.WhenRoomOpened
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IEnterRoomUpdate>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IRoomUserUpdate> ITextChat.WhenUserEntersRoom
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IRoomUserUpdate>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IRoomUserUpdate> ITextChat.WhenUserLeavesRoom
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IRoomUserUpdate>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IAddMessageUpdate> ITextChat.WhenMessageReceived
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IAddMessageUpdate>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IRoomUserUpdate> ITextChat.WhenUserTypes
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IRoomUserUpdate>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<SysMessage> ITextChat.WhenSysMessageReceived
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<SysMessage>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<SysMessage> ITextChat.WhenPrivateRequestAnswerReceived
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<SysMessage>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<IUserInfo> ITextChat.WhenPrivateRequestReceived
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<IUserInfo>>() != null);
                throw new NotImplementedException();
            }
        }

        IObservable<Exception> ITextChat.WhenErrorOccurred
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservable<Exception>>() != null);
                throw new NotImplementedException();
            }
        }

        void IDisposable.Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
